/* this is the scanner example from the JLex website 
   (with small modifications to make it more readable) */
package lex;
import parser.sym;
import java_cup.runtime.Symbol;
%%
%public
%class Lexer
%cup
%{
  public StringBuffer strLex = new StringBuffer();
  private int line = 1;
  private int col = 1;
  private Lut lut = new Lut();
  
%} 

letter=[A-Za-z]
digit=[0-9]
newline=\r|\n|\r\n

WS=[\ \t\b\012]
ID = ({letter}|_)({letter}|{digit}|_)*
ID_INVALID = {digit}+(({letter}|_)+{digit}*)+
LIT_INT = {digit}+
LIT_BOOLEAN = "TRUE" | "FALSE"
hexa = [0-9A-Fa-f]
hexa_invalid = [^0-9A-Fa-f]
lit_hexa = \\x{hexa}{hexa}
lit_hexa_invalid = \\x{hexa_invalid}{hexa_invalid}
printable = \\[\"nrt0]|{lit_hexa}
printable_invalid = \\[^\"nrt0]|{lit_hexa_invalid}
LIT_STR=({printable}|[^\n\"\\]|\\{WS}+\\)*
LIT_STR_INVALID=({printable}|{printable_invalid}|[^\n\r\"\\]|\\{WS}+\\)*

%% 
		 "//".* {++line;col=1;}
		   {WS} {col+=yylength();}
			"," { String info = "VIRGULA\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
			      strLex.append(info+"\n"); 
			      return new Symbol(sym.VIRGULA,line,col-1); }  
			":" { String info = "DOIS PONTOS\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.DOISPONTOS,line,col-1); }
			";" { String info = "PONTO VIRGULA\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.PONTOVIRGULA,line,col-1); }
			"." { String info = "PONTO \tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.PONTO,line,col-1); }
			"(" { String info = "ABRE PARENTESES\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.ABREP,line,col-1); }
			")" { String info = "FECHA PARENTESES\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.FECHAP,line,col-1); }

	/*	  "MOD" { String info = "MOD\tLinha: "+line+"\tColuna:"+col+" "+(col+=3);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MOD,line,col-3); }*/
			"+" { String info = "MAIS\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MAIS,line,col-1); }
			"-" { String info = "MENOS\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MENOS,line,col-1); }
			"*" { String info = "MULT\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MULT,line,col-1); }
			"/" { String info = "DIVI\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.DIVI,line,col-1); }
  
  
	/*	  "AND" { String info = "AND\tLinha: "+line+"\tColuna:"+col+" "+(col+=3);
				  strLex.append(info+"\n");
			      return new Symbol(sym.AND,line,col-3); }
		   "OR" { String info = "OR\tLinha: "+line+"\tColuna:"+col+" "+(col+=2);
				  strLex.append(info+"\n");
			      return new Symbol(sym.OR,line,col-2); }
		  "NOT" { String info = "NOT\tLinha: "+line+"\tColuna:"+col+" "+(col+=3);
				  strLex.append(info+"\n");*/
			      return new Symbol(sym.NOT,line,col-3); }
  			"#" { String info = "DIFERENTE\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.DIFERENTE,line,col-1); }
	 	    "=" { String info = "IGUAL\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.IGUAL,line,col-1); }
			"<" { String info = "MENOR\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MENOR,line,col-1); }
		   "<=" { String info = "MENOR IGUAL\tLinha: "+line+"\tColuna:"+col+" "+(col+=2);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MENORIGUAL,line,col-2); }
		    ">" { String info = "MAIOR\tLinha: "+line+"\tColuna:"+col+" "+(col+=1);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MAIOR,line,col-1); }
		   ">=" { String info = "MAIOR IGUAL\tLinha: "+line+"\tColuna:"+col+" "+(col+=2);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MAIORIGUAL,line,col-2); }
		   ":=" { String info = "ATRIBUICAO\tLinha: "+line+"\tColuna:"+col+" "+(col+=2);
				  strLex.append(info+"\n");
			      return new Symbol(sym.ATRIBUICAO,line,col-2); }
  
/*	   "MODULE"|"module" { String info = "MODULE\tLinha: "+line+"\tColuna:"+col+" "+(col+=6);
				  strLex.append(info+"\n");
			      return new Symbol(sym.MODULE,line,col-6); }
		  "VAR" { String info = "VAR\tLinha: "+line+"\tColuna:"+col+" "+(col+=3); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.VAR,line,col-3); }
    "PROCEDURE" { String info = "PROCEDURE\tLinha: "+line+"\tColuna:"+col+" "+(col+=9); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.PROCEDURE,line,col-9); }
	 "FUNCTION" { String info = "FUNCTION\tLinha: "+line+"\tColuna:"+col+" "+(col+=8); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.FUNCTION,line,col-8); }
		"BEGIN" { String info = "BEGIN\tLinha: "+line+"\tColuna:"+col+" "+(col+=5); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.BEGIN,line,col-5); }
		  "END" { String info = "END\tLinha: "+line+"\tColuna:"+col+" "+(col+=3); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.END,line,col-3); }
  
		   "IF" { String info = "IF\tLinha: "+line+"\tColuna:"+col+" "+(col+=2); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.IF,line,col-2); }
		 "THEN" { String info = "THEN\tLinha: "+line+"\tColuna:"+col+" "+(col+=4); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.THEN,line,col-4); }
		 "ELSE" { String info = "ELSE\tLinha: "+line+"\tColuna:"+col+" "+(col+=3); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.ELSE,line,col-4); }
		"ELSIF" { String info = "ELSEIF\tLinha: "+line+"\tColuna:"+col+" "+(col+=5); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.ELSIF,line,col-5); }
		"WHILE" { String info = "WHILE\tLinha: "+line+"\tColuna:"+col+" "+(col+=5); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.WHILE,line,col-5); }
  		   "DO" { String info = "DO\tLinha: "+line+"\tColuna:"+col+" "+(col+=2); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.DO,line,col-2); }
       "REPEAT" { String info = "REPEAT\tLinha: "+line+"\tColuna:"+col+" "+(col+=6); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.REPEAT,line,col-3); }
	    "UNTIL" { String info = "UNTIL\tLinha: "+line+"\tColuna:"+col+" "+(col+=5); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.UNTIL,line,col-5); }
       "RETURN" { String info = "RETURN\tLinha: "+line+"\tColuna:"+col+" "+(col+=6); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.RETURN,line,col-6); }
     "CONTINUE" { String info = "CONTINUE\tLinha: "+line+"\tColuna:"+col+" "+(col+=8); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.CONTINUE,line,col-8); }
        "BREAK" { String info = "BREAK\tLinha: "+line+"\tColuna:"+col+" "+(col+=5); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.BREAK,line,col-5); }
		  "FOR" { String info = "FOR\tLinha: "+line+"\tColuna:"+col+" "+(col+=3); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.FOR,line,col-3); }
		   "TO" { String info = "TO\tLinha: "+line+"\tColuna:"+col+" "+(col+=2); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.TO,line,col-2); }

  	    "WRITE" { String info = "WRITE\tLinha: "+line+"\tColuna:"+col+" "+(col+=5); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.WRITE,line,col-5); }
  	  "WRITELN" { String info = "WRITELN\tLinha: "+line+"\tColuna:"+col+" "+(col+=7); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.WRITELN,line,col-7); }
  		 "READ" { String info = "READ\tLinha: "+line+"\tColuna:"+col+" "+(col+=4); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.READ,line,col-4); }
  	  "INTEGER" { String info = "INTEGER\tLinha: "+line+"\tColuna:"+col+" "+(col+=6); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.INTEGER,line,col-6); }
	  "BOOLEAN" { String info = "BOOLEAN\tLinha: "+line+"\tColuna:"+col+" "+(col+=6); 
				  strLex.append(info+"\n");
			      return new Symbol(sym.BOOLEAN,line,col-6); }
  	  
  {LIT_BOOLEAN} { String str =  yytext();
				  String info = "BOOLEAN <"+str+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength());
				  strLex.append(info+"\n");
				  if (str.equals("FALSE"))
			      	return new Symbol(sym.LITBOOLEAN,line,col-5,false);
			      if (str.equals("TRUE"))
			      	return new Symbol(sym.LITBOOLEAN,line,col-4,true); }
*/
  \"{LIT_STR}\" { String str =  yytext().substring(1,yytext().length()-1);
			      String info = "STRING <"+str+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength());
				  strLex.append(info+"\n");
			      return new Symbol(sym.STRING,line,col-yylength(),str); }
  
	  {LIT_INT} { String info = "INTEIRO <"+yytext()+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength());
				  strLex.append(info+"\n");
			      return new Symbol(sym.LITINT,line,col-yylength(),yytext()); }  

		   {ID} { String info = "ID <"+yytext()+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength()); 
				  strLex.append(info+"\n");
				  String id = yytext();
				  Integer s = lut.get(id);
				  if (s==null)
			      	return new Symbol(sym.ID,line,col-yylength(),yytext());
				  if (s==sym.LITBOOLEAN) {
				  	if (id.toUpperCase().equals("TRUE"))
				  		return new Symbol(sym.LITBOOLEAN,line,col-4,true);
				  	else
				  		return new Symbol(sym.LITBOOLEAN,line,col-5,false);
				  }
			      return new Symbol(s,line,col-yylength(),yytext()); }  

	  {newline} {++line;col=1;}
  
\"{LIT_STR_INVALID}\" {
			      String str =  yytext().substring(1,yytext().length()-1);
			      String info = "STRING INVALID <"+str+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength());
			  	  System.out.println(info); }

	\"{LIT_STR} { String str =  yytext().substring(1,yytext().length());
			      String info = "STRING UNCLOSED <"+str+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength());
				  System.out.println(info); } 
  
			  . { String info = "INVALID CARACTER <"+yytext()+">\tLinha: "+line+"\tColuna:"+col+" "+(col+=yylength());
				  System.out.println(info); }